﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Domain.Logging
{
    /// <summary>
    /// Logs information about the application state 
    /// </summary>
    public abstract class LogService : IDisposable
    {
        private bool _enableTimestampping = true;
        private bool _logWarnings = true;
        private bool _logMessages = true;

        /// <summary>
        /// Writes an error message to the logger
        /// </summary>
        /// <param name="message"></param>
        public void WriteError(string message)
        { WriteError("{0}", message); }

        /// <summary>
        /// Writes a formatted error message to the logger
        /// </summary>
        /// <param name="message"></param>
        /// <param name="args"></param>
        public void WriteError(string message, params object[] args)
        { writeFormattedErrorMessage(FormattedDate() + " - ERROR: " + message, args); }

        protected abstract void writeFormattedErrorMessage(string message, params object[] args);

        /// <summary>
        /// Writes a warning message to the logger
        /// </summary>
        /// <param name="message"></param>
        void WriteWarning(string message)
        { WriteWarning("{0}", message); }

        /// <summary>
        /// Writes a formatted warning message to the logger
        /// </summary>
        /// <param name="message"></param>
        /// <param name="args"></param>
        public void WriteWarning(string message, params object[] args)
        {
            if (LogWarnings)
                writeFormattedWarningMessage(FormattedDate() + " - WARNING:" + message, args);
        }

        protected abstract void writeFormattedWarningMessage(string message, params object[] args);

        /// <summary>
        /// Writes a message to the logger
        /// </summary>
        /// <param name="message"></param>
        public void WriteMessage(string message)
        { WriteMessage("{0}", message); }

        /// <summary>
        /// Writes a formatted message to the logger
        /// </summary>
        /// <param name="message"></param>
        /// <param name="args"></param>
        public void WriteMessage(string message, params object[] args)
        {
            if (LogMessages)
                writeFormattedMessage(FormattedDate() + message, args);
        }

        protected abstract void writeFormattedMessage(string message, params object[] args);

        private string FormattedDate()
        {
            return String.Format("{0}: ", DateTime.Now.ToString());
        }

        /// <summary>
        /// Forces the logger to flush its contents to a backing store
        /// </summary>
        public abstract void ForceFlush();
        
        /// <summary>
        /// Enables or disables timestamping on messages
        /// </summary>
        bool TimestampLogs
        {
            get { return _enableTimestampping; }
            set { _enableTimestampping = value; }
        }

        /// <summary>
        /// Log warnings in this logger
        /// </summary>
        bool LogWarnings
        { 
            get { return _logWarnings; }
            set { _logWarnings = value; }
        }

        /// <summary>
        /// Log ordinary messages in the logger
        /// </summary>
        bool LogMessages
        { get { return _logWarnings; }
            set { _logWarnings = value; }
        }

        public void Dispose()
        {
            OnDispose(true);
        }

        protected virtual void OnDispose(bool disposing)
        {
        }
    }
}
